<template>
  <div v-if = "playlist.length > 0">
    <div class = "normal-play" v-show = "screenSize">
      <div class = "bg-img" :style = "bgStyle"></div>
      <div class = "top">
        <div class = "to-mini">
          <i class = "icon-back" @click = "toMini"></i>
        </div>
        <div class = "desc">
          <h1>{{ currentSong.name }}</h1>
          <p>{{ currentSong.singer }}</p>
        </div>
      </div>
      <slide class = "middle"
             ref = "slide"
             :loop = "false"
             :dots = "false"
             @pagechange = "pageChange">
        <div class = "middle-left">
          <div class = "cd">
            <img :src = "currentSong.img">
          </div>
          <div class="current-lyric">
            <span>{{ currentLyric }}</span>
          </div>
          <div class = "time">
            <span class = "t left">{{ currentTime | format }}</span>
            <div class = "progress-wrapper">
              <progress-bar ref = "progress"
                            :percent = "percent"
                            @percentchange = "percentChange"
                            @percentchanging = "percentChanging">
              </progress-bar>
            </div>
            <span class = "t right">{{ currentSong.time | format }}</span>
          </div>
        </div>
        <scroll class = "middle-right" v-if = "lyric" ref = "scroll">
          <ul class = "lyric-wrapper" v-if="lyric.lines.length > 0">
            <li class = "lyric-line"
                :class="{'active': currentLine === index}"
                v-for = "(line,index) in lyric.lines"
                :key = "index" ref = "lines">{{ line.txt}}
            </li>
          </ul>
          <div v-else class="lyric-empty">
            <h1>该歌曲暂无歌词</h1>
          </div>
        </scroll>
      </slide>
      <div class = "bottom" v-show = "controlPage === 0">
        <ul class = "icons">
          <li><i :class = "modeCls" @click = "changeMode"></i></li>
          <li><i class = "icon-prev" @click = "prevSong"></i></li>
          <li><i class = "play" :class = "playCls" @click = "togglePlayFlag"></i></li>
          <li><i class = "icon-next" @click = "nextSong"></i></li>
          <li><i :class = "likeIcon(currentSong)" @click = "toggleLike(currentSong)"></i></li>
        </ul>
      </div>
    </div>
    <div class = "mini" v-show = "!screenSize" @click = "toMax">
      <div class = "flex-wrapper">
        <div class = "img">
          <img :src = "currentSong.img" width = "40" height = "40">
        </div>
        <div class = "text">
          <h1>{{ currentSong.name }}</h1>
          <p>{{ currentSong.singer }}</p>
        </div>
        <div class = "diver"></div>
        <div class = "progress-wrapper">
          <progress-circle :radius = "50" :percent = "percent">
            <i class = "icon-common"
               :class = "miniIcon"
               @click.stop = "togglePlayFlag"></i>
          </progress-circle>
        </div>
        <div class = "icon">
          <i class = "icon-playlist" @click.stop = "showDialog"></i>
        </div>
      </div>
    </div>
    <play-list :songs = "dialogs"
               :current-song = "currentSong"
               @select = "changeSong"
               v-show = "dialogFlag">
    </play-list>
    <audio :src = "currentSong.url" ref = "audio" @canplay = "canplay" @ended = "ended"
           @timeupdate = "timeUpdate"></audio>
  </div>
</template>

<script>
    import playList from "@/components/play-list/playList";
    import Slide from "@/base/slide/Slide";
    import ProgressBar from "@/base/progress-liner/ProgressBar";
    import ProgressCircle from "@/base/progress-circle/ProgressCircle";
    import {mapGetters, mapMutations} from 'vuex'
    import {mode, screen, play, dialog} from "@/config/mode-config/config";
    import Lyric from 'lyric-parser'
    import Scroll from "@/base/scroll/Scroll";
    import {likeListOptions, modeChange} from "@/common/js/mixin";

    export default {
        name: "Player",
        mixins: [modeChange, likeListOptions],
        components: {playList, Scroll, Slide, ProgressBar, ProgressCircle},
        computed: {
            ...mapGetters('song', [
                'currentSong',
                'screenSize',
                'playlist',
                'dialogs',
                'play',
                'index',
                'moving'
            ]),
            dialogFlag() {
                return this.$store.getters.dialogFlag
            },
            bgStyle() {
                return `background-image:url(${this.currentSong.img})`
            },
            playCls() {
                return this.play ? 'icon-pause' : 'icon-play'
            },
            miniIcon() {
                return this.play ? 'icon-pause-mini' : 'icon-play-mini'
            },
            percent() {
                return this.currentTime / this.currentSong.time
            }
        },
        data() {
            return {
                currentTime: 0,
                lyric: null,
                controlPage: 0,
                currentLine: 0,
                currentLyric: ''
            }
        },
        filters: {
            format(time) {
                let minute = time / 60 | 0
                let second = time % 60 | 0
                if (second < 10)
                    second = '0' + second
                return `${minute}:${second}`
            }
        },
        methods: {
            ...mapMutations('song', ['setPlay', 'setSize', 'setIndex']),
            toMini() {
                this.setSize(screen.mini)
            },
            toMax() {
                this.setSize(screen.full)
            },
            changeSong(song) {
                let index = this.playlist.findIndex(item => {
                    return item.id === song.id
                })
                this.setIndex(index)
            },
            timeUpdate(e) {
                if (this.moving) return
                this.currentTime = e.target.currentTime
            },
            pageChange(page) {
                this.controlPage = page
            },
            togglePlayFlag() {
                this.setPlay(!this.play)
                if(this.lyric)
                    this.lyric.togglePlay()
            },
            percentChange(percent) {
                this.currentTime = this.$refs.audio.currentTime = this.currentSong.time * percent
                if(this.lyric)
                    this.lyric.seek(this.currentTime * 1000)
            },
            percentChanging(percent) {
                this.currentTime = this.currentSong.time * percent
            },
            prevSong() {
                let index = this.index
                if (index === 0)
                    index = this.playlist.length
                this.setIndex(index - 1)
            },
            nextSong() {
                let index = this.index
                if (index === this.playlist.length - 1)
                    index = -1
                this.setIndex(index + 1)
            },
            canplay() {
                if (this.play)   this.$refs.audio.play()
            },
            ended() {
                if (this.mode == mode.loop) this.$refs.audio.currentTime = 0
                else this.nextSong()
            },
            async getLyric() {
                this.lyric = new Lyric(await this.currentSong.getLyric(), this.handleLyric)
                if(this.play)
                    this.lyric.play()
            },
            handleLyric({txt,lineNum}) {
                this.currentLine = lineNum
                this.currentLyric = txt
                if(lineNum > 5)
                    lineNum -= 5
                let el = this.$refs.lines[lineNum]
                this.$refs.scroll.scrollToEle(el,0)
            },
            showDialog() {
                this.$store.commit('setDialogFlag', dialog.show)
            }
        },
        watch: {
            play(play) {
                if (!this.playlist.length) return
                this.$nextTick(()=>{
                    if(play){
                        this.$refs.audio.play()
                    }else {
                        this.$refs.audio.pause()
                    }
                })
            },
            currentSong(newsong) {
                if (!this.playlist.length) return
                if(this.lyric){
                    this.lyric.stop()
                    this.currentLyric = ''
                    this.currentLine = 0
                    this.currentTime = 0
                }
                this.addRecent(newsong)
                this.setPlay(play.playing)
                this.getLyric()
            }
        },
    }
</script>

<style scoped lang = "stylus">
  @import "~common/stylus/variable"
  .normal-play
    position fixed
    top 0
    bottom 0
    left 0
    right 0
    background $color-background
    z-index 150

    .bg-img
      position absolute
      top 0
      width 100%
      height 100%
      background-size cover
      background-position center
      filter blur(20px)
      opacity 0.6
      z-index -1

    .top
      height 64px

      .to-mini
        position absolute
        top 10px
        left 1rem
        transform rotateZ(-90deg)

        .icon-back
          font-size 2rem
          color $color-theme

      .desc
        text-align center
        color $color-text
        line-height 2rem
        overflow hidden

        h1
          margin-top 5px
          font-size $font-size-large

        p
          font-size $font-size-medium

    .middle
      position fixed
      top 64px
      left 0
      right 0
      bottom 60px

      .middle-left
        width 100% // 必须有，否则 进度条的 clientWidth = 0
        position relative
        margin-top -20px
        overflow hidden

        .cd
          position relative
          top 50%
          transform translateY(-50%)
          width 80%
          height 0
          padding-top 80%
          margin 0 auto
          box-sizing border-box
          border 10px solid rgba(5, 5, 5, .5)
          border-radius 50%
          overflow hidden

          img
            position absolute
            top 0
            width 100%

        .current-lyric
          position absolute
          bottom 40px
          width 100%
          text-align center
          span
            color $color-text-l
            font-size $font-size-medium
        .time
          position absolute
          bottom 10px
          width 100%
          padding 0 30px
          box-sizing border-box
          display flex
          align-items center

          .progress-wrapper
            flex 1
            margin 0 10px

          .t
            color $color-text

      .middle-right
        margin-top 20px
        overflow hidden

        .lyric-wrapper
          text-align center

          .lyric-line
            line-height 2rem
            color $color-text-l
            font-size $font-size-medium-x
            &.active
              color $color-text
        .lyric-empty
           position absolute
           width 50%
           top 0
           bottom 0
           display flex
           justify-content center
           align-items center
           h1
            color $color-text-l
            font-size $font-size-large-x

    .bottom
      position fixed
      bottom 0
      width 100%
      height 60px

      .icons
        display flex
        height 100%
        align-items center
        justify-content space-evenly
        padding 0 30px
        font-size 2rem
        color $color-theme

        .play
          font-size 3rem

  .mini
    position fixed
    height 60px
    bottom 0
    left 0
    right 0

    .flex-wrapper
      display flex
      background $color-highlight-background
      padding 5px 12px 10px
      align-items center

      .img
        img
          border-radius 50%

      .text
        margin-left 10px
        line-height 1.5rem

        h1
          color $color-text
          font-size $font-size-medium

        p
          font-size $font-size-small
          color $color-text-d

      .diver
        flex 1

      .progress-wrapper
        width 50px
        height 50px
        border-radius 50%

        .icon-common
          position absolute
          top 50%
          transform translateY(-57%)
          left 0
          right 0
          text-align center
          font-size 1.9rem
          color $color-theme

      .icon
        margin 0 10px

        .icon-playlist
          font-size 1.8rem
          color $color-theme

  .red
    color $color-sub-theme
</style>
